package cc.yaomm.service.basic.service.user;

import cc.yaomm.common.basic.enums.StatusEnum;
import cc.yaomm.common.basic.util.BeanUtils;
import cc.yaomm.service.basic.entity.user.Permissions;
import cc.yaomm.service.basic.entity.user.Roles;
import cc.yaomm.service.basic.entity.user.UsersPermissionsRef;
import cc.yaomm.service.basic.mapper.user.PermissionsMapper;
import cc.yaomm.service.basic.mapper.user.RolesMapper;
import cc.yaomm.service.basic.mapper.user.UsersPermissionsRefMapper;
import cc.yaomm.service.basic.mapper.user.po.RoleParamPO;
import cc.yaomm.service.basic.service.user.bo.RoleParamBO;
import cc.yaomm.service.basic.service.user.bo.RoleResultBO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;

import javax.validation.Valid;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * Created by XQL on 2021/6/9.
 */
@Service
@Validated
public class RoleService {

    @Autowired
    private RolesMapper rolesMapper;

    @Autowired
    private PermissionsMapper permissionsMapper;

    @Autowired
    private UsersPermissionsRefMapper usersPermissionsRefMapper;

    /**
     * 分页查询
     *
     * @param paramBO
     * @return
     */
    public List<RoleResultBO> findPage(RoleParamBO paramBO) {
        RoleParamPO paramPO = paramBO.convert(RoleParamPO.class);
        List<Roles> rolesList = rolesMapper.findByPage(paramPO);
        return BeanUtils.mapList(rolesList, RoleResultBO.class);
    }

    /**
     * 分页统计
     *
     * @param paramBO
     * @return
     */
    public Integer countPage(RoleParamBO paramBO) {
        RoleParamPO paramPO = paramBO.convert(RoleParamPO.class);
        return rolesMapper.countByPage(paramPO);
    }

    /**
     * create/edit role
     */
    @Transactional
    public void save(@Valid RoleParamBO paramBO) {
        Roles roles = paramBO.convert(Roles.class);
        if (Objects.isNull(paramBO.getId())) { //insert
            roles.setCreateBy(roles.getUpdateBy());
            rolesMapper.insert(roles);
        } else { //update
            roles.setOwnerType(null); //no update
            roles.setOwnerId(null); //no update
            rolesMapper.updateById(roles);
        }
    }

    /**
     * lock/unlock role
     *
     * @param id
     * @param status
     */
    @Transactional
    public void lock(Long id, StatusEnum status) {
        Assert.notNull(id, "参数ID，不能为空");
        Assert.notNull(status, "参数status，不能为空");
        Roles roles = rolesMapper.get(id);
        Assert.notNull(roles, "未查询到此角色");

        //判断状态是否一致
        if (!roles.getStatus().equals(status)) {
            roles.setStatus(status);
            rolesMapper.updateById(roles);
        }
    }

    /**
     * set role permission
     *
     * @param id
     * @param permissionIds
     */
    @Transactional
    public void setPermission(Long id, List<Long> permissionIds) {
        Assert.notNull(id, "参数ID，不能为空");
        Assert.isTrue(!CollectionUtils.isEmpty(permissionIds), "参数permissionIds，不能为空");
        Roles roles = rolesMapper.get(id);
        Assert.notNull(roles, "未查询到此角色");

        List<Permissions> permissionsList = permissionsMapper.findByIds(permissionIds);
        Assert.isTrue(!CollectionUtils.isEmpty(permissionsList), "未查询有效的权限");

        //清空角色关联的权限数据
        usersPermissionsRefMapper.deletePermission(id);

        List<UsersPermissionsRef> refList = permissionsList.stream()
                .map(x -> new UsersPermissionsRef().setRoleId(id).setPermissionId(x.getId()))
                .collect(Collectors.toList());

        usersPermissionsRefMapper.batchInsert(refList);
    }
}
